﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FinalPointSet.Model.Model.Knowledge
{
    /// <summary>
    /// 知识点
    /// </summary>
    public class KnowledgePoint
    {
        /// <summary>
        /// ID
        /// </summary>
        public int ID { get; set; } = -1;
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; } = "";
        /// <summary>
        /// 语言
        /// </summary>
        public Language Language { get; set; } = new();
        /// <summary>
        /// 关键词
        /// </summary>
        public string Keyword { get; set; } = "";
        /// <summary>
        /// 内容
        /// </summary>
        public string Content { get; set; } = "";
        /// <summary>
        /// 权重,用于搜索名中判断与排序
        /// </summary>
        public double Weight { get; set; }
        public KnowledgePoint()
        {

        }
        public KnowledgePoint(int id, string name, Language language, string keyword, string content)
        {
            ID = id;
            Name = name;
            Language = language;
            Keyword = keyword;
            Content = content;
        }
        public static KnowledgePoint Clone(KnowledgePoint kp)
        {
            return new KnowledgePoint()
            {
                ID = kp.ID,
                Name = kp.Name,
                Language = kp.Language,
                Keyword = kp.Keyword,
                Content = kp.Content,
                Weight = kp.Weight,
            };
        }

        public override string? ToString()
        {
            return $"ID={ID},Name={Name},Language={Language},Keyword={Keyword},Content={Content}";
        }
    }

    /// <summary>
    /// 知识点映射规则序列化转换器
    /// </summary>
    public class KnowledgePointConverter : JsonConverter<KnowledgePoint>
    {
        /// <summary>
        /// 语言集合
        /// </summary>
        private readonly List<Language> languages = [];
        public KnowledgePointConverter() { }
        public KnowledgePointConverter(List<Language> languages)
        {
            this.languages = languages;
        }
        public override void WriteJson(JsonWriter writer, KnowledgePoint? value, JsonSerializer serializer)
        {
            ArgumentNullException.ThrowIfNull(value);
            //只序列化Name属性
            JObject obj = new()
            {
                { "ID", value.ID },
                { "Name", value.Name },
                { "Language", value.Language.Name },
                { "Keyword", value.Keyword },
                { "Content", value.Content }
            };
            obj.WriteTo(writer);
        }

        public override KnowledgePoint ReadJson(JsonReader reader, Type objectType, KnowledgePoint? existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var obj = JObject.Load(reader);
            return Parse(obj, serializer, languages);
        }

        public static KnowledgePoint Parse(JObject jsonObj, JsonSerializer serializer, List<Language> languages)
        {
            KnowledgePoint result = new();
            // 反序列化单独的属性
            if (jsonObj["ID"] is JToken jtID)
                result.ID = int.Parse(jtID.ToString());
            if (jsonObj["Name"] is JToken jtName)
                result.Name = jtName.ToString();
            if (jsonObj["Keyword"] is JToken jtKeyword)
                result.Keyword = jtKeyword.ToString();
            if (jsonObj["Content"] is JToken jtContent)
                result.Content = jtContent.ToString();

            // 反序列化语言
            if (jsonObj["Language"] is JToken jtLanguage && languages != null && languages.Count > 0)
            {
                string languageName = jtLanguage.ToString() ?? string.Empty;
                Language language = languages.FirstOrDefault(lang => languageName.Equals(lang.Name), new());
                result.Language = Language.Clone(language);
            }
            return result;
        }
    }
}
